package compilador.lexico;

import java.util.HashMap;
import java.util.Map;

/**
 * Representação da tabela de palavras reservadas, implementada como um hash
 * para realizar buscas eficientes.
 *
 * @author Carlos H V Pinto
 * @author Lucas S Bueno
 */
public final class TabelaReservados {

    private Map<String, TipoToken> tabela;

    /*
     * Constrói a tabela de palavras/símbolos reservados, associando os
     * lexemas aos tipos de tokens.
     */
    public TabelaReservados() {
        String[] lexemas = {"algoritmo", "fim_algoritmo", "declare", "literal",
            "inteiro", "real", "logico", "leia", "escreva", "se", "entao",
            "senao", "fim_se", "caso", "seja", "fim_caso", "tipo", "para",
            "ate", "faca", "fim_para", "enquanto", "fim_enquanto", "procedimento",
            "fim_procedimento", "funcao", "fim_funcao", "ou", "e", "nao",
            "registro", "fim_registro", "var", "constante", "verdadeiro", "falso",
            "retorne", ":", ",", "^", "(", ")", "-", "%", "*", "/", "+", "&", "=", "<", ">", ".",
            "[", "]", "<-", "<>", "<=", ">=", ".."};

        TipoToken[] tipos = {TipoToken.PR_Algoritmo, TipoToken.PR_FimAlgoritmo,
            TipoToken.PR_Declare, TipoToken.PR_Literal, TipoToken.PR_Inteiro,
            TipoToken.PR_Real, TipoToken.PR_Logico, TipoToken.PR_Leia,
            TipoToken.PR_Escreva, TipoToken.PR_Se, TipoToken.PR_Entao,
            TipoToken.PR_Senao, TipoToken.PR_FimSe, TipoToken.PR_Caso,
            TipoToken.PR_Seja, TipoToken.PR_FimCaso, TipoToken.PR_Tipo,
            TipoToken.PR_Para, TipoToken.PR_Ate, TipoToken.PR_Faca,
            TipoToken.PR_FimPara, TipoToken.PR_Enquanto, TipoToken.PR_FimEnquanto,
            TipoToken.PR_Procedimento, TipoToken.PR_FimProcedimento,
            TipoToken.PR_Funcao, TipoToken.PR_FimFuncao, TipoToken.PR_Ou,
            TipoToken.PR_E, TipoToken.PR_Nao, TipoToken.PR_Registro,
            TipoToken.PR_FimRegistro, TipoToken.PR_Var, TipoToken.PR_Constante,
            TipoToken.PR_Verdadeiro, TipoToken.PR_Falso, TipoToken.PR_Retorne,
            TipoToken.SR_DoisPontos, TipoToken.SR_Virgula,
            TipoToken.SR_Circunflexo, TipoToken.SR_AbreParenteses,
            TipoToken.SR_FechaParenteses, TipoToken.SR_Subtracao, TipoToken.SR_Modulo,
            TipoToken.SR_Multiplicacao, TipoToken.SR_Divisao, TipoToken.SR_Adicao,
            TipoToken.SR_Endereco, TipoToken.SR_Igual, TipoToken.SR_Menor, TipoToken.SR_Maior,
            TipoToken.SR_Ponto, TipoToken.SR_AbreColchetes, TipoToken.SR_FechaColchetes,
            TipoToken.SR_Atribuicao, TipoToken.SR_Diferente, TipoToken.SR_MenorIgual,
            TipoToken.SR_MaiorIgual, TipoToken.SR_Concatenacao
        };

        tabela = new HashMap<String, TipoToken>();
        for (int i = 0; i < lexemas.length; i++) {
            tabela.put(lexemas[i], tipos[i]);
        }
    }

    /**
     * Busca a palavra especificada na tabela de palavras reservadas.
     *
     * @param lexema Chave de busca para a tabela de palavras/simbolos
     * reservados.
     * @return Tipo de token mapeado pela chave de busca. Se a chave não está
     * mapeada retorna null.
     */
    public TipoToken busca(String lexema) {
        return tabela.get(lexema);
    }
}
